#include "Interactiv/gvector3.h"
#include "Interactiv/csphere.h"

#include "Interactiv/intersectresult.h"
CSphere::CSphere()
{    
}
CSphere::CSphere(GVector3 c,double r)
{
    center=c;
    radius=r;
}
CSphere::CSphere(CSphere& s)
{
     center=s.getCenter();
     radius=s.getRadius();
}
CSphere::~CSphere()
{
}
void CSphere::setCenter(GVector3& c)
{
     center=c;
}
void CSphere::setRadius(double r)
{
    radius=r;
}
GVector3 CSphere::getCenter()
{
    return center;
}

double CSphere::GetRadiusSquare()
{
	return radius * radius;
}

double CSphere::getRadius()
{
    return radius;
}
GVector3 CSphere::getNormal(GVector3 p)
{
    return p-center; //
}

//
bool CSphere::Intersect(CRay ray, float& t0, float& t1)
{
	GVector3 oc = center - ray.getOrigin();
	float projoc = ray.getDirection().dotMul(oc);

	if (projoc < 0)
		return false;

	float oc2 = oc.dotMul(oc);

	float distance2 = oc2 - projoc * projoc;

	if (distance2 > GetRadiusSquare())
		return false;

	float discriminant = GetRadiusSquare() - distance2;
	if(discriminant < 0.01)
		t0 = t1 = projoc;
	else
	{
		discriminant = sqrt(discriminant);
		t0 = projoc - discriminant;
		t1 = projoc + discriminant;
		if (t0 < 0)
			t0 = t1;
	}
	return true;
}

IntersectResult CSphere::isIntersected(CRay& _ray)
{
      IntersectResult result = IntersectResult::noHit();
      GVector3 v = _ray.getOrigin() - center;
      float a0 = v.dotMul(v) - radius*radius;
      float DdotV = _ray.getDirection().dotMul(v);

     if(DdotV <= 0)
     { 
       float discr = DdotV * DdotV - a0;
       if (discr >= 0)
       {
         result.isHit=1;
         result.object = this;
         result.distance=-DdotV - sqrt(discr);
         result.position=_ray.getPoint(result.distance);
         result.normal = result.position-center;
         result.normal.normalize();

	     return result;
    }
  } 

  result.isHit = 0;

  return result;
}
